package com.fc.happyteam.shiro.common;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SessionContext;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;

import static com.fc.happyteam.utils.HttpContextUtils.isAjax;


public class MyDefaultWebSessionManager extends DefaultWebSessionManager {

    private static final Logger log = LoggerFactory.getLogger(MyDefaultWebSessionManager.class);
    public static final String SESSION_ID_HEADER_NAME = "sid";

    public MyDefaultWebSessionManager() {
        super();
    }

    @Override
    protected void onStart(Session session, SessionContext context) {
        if (!WebUtils.isHttp(context)) {
            log.debug("SessionContext argument is not HTTP compatible or does not have an HTTP request/response " +
                    "pair. No session ID cookie will be set.");
            return;

        }
        HttpServletRequest request = WebUtils.getHttpRequest(context);
        if(!isAjax(request)){
            super.onStart(session, context);
        }else{
            log.debug("Http request from APP.");
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
        }
    }

    @Override
    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
        if(!isAjax(request)){
            return super.getSessionId(request, response);
        }

        HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
        Serializable id = httpServletRequest.getHeader(SESSION_ID_HEADER_NAME);

        if (id == null) {
            //try uppercase:
            id = httpServletRequest.getHeader(SESSION_ID_HEADER_NAME.toUpperCase());
        }

        if (id != null) {
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
            //automatically mark it valid here.  If it is invalid, the
            //onUnknownSession method below will be invoked and we'll remove the attribute at that time.
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
        } else {
            //still null, read from cookie like web
            id = super.getSessionId(request, response);
        }

        return id;
    }
}
